﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Chapter13
{
    using System.Collections;

    partial class Program
    {
        internal static void Begin(Action action, bool active = false)
        {
            if (active)
            {
                Console.WriteLine("开始演示：");
                action();
                Console.WriteLine("演示完毕：");
                Console.ReadLine();
            }
        }

        private sealed class Point : IComparable<Point>
        {
            private int x, y;

            internal Point(int x, int y)
            {
                this.x = x;
                this.y = y;
            }

            public int CompareTo(Point other)
            {
                return Math.Sign(Math.Sqrt(x * x + y * y) - Math.Sqrt(other.x * other.x + other.y * other.y));
            }

            public override string ToString()
            {
                return string.Format("({0}, {1})", x, y);
            }
        }

        internal static void C02()
        {
            Point[] points = new Point[] { new Point(3, 3), new Point(1, 2) };
            if (points[0].CompareTo(points[1]) > 0)
            {
                Point tempPoint = points[0];
                points[0] = points[1];
                points[1] = tempPoint;
            }
            Console.WriteLine("Points from closest to (0, 0) to farthest:");
            foreach (Point p in points)
            {
                Console.WriteLine(p);
            }
        }

        private class Base : IDisposable, IComparable
        {
            public void Dispose()
            {
                Console.WriteLine("Base's Dispose");
            }

            int IComparable.CompareTo(object obj)
            {
                Console.WriteLine("Base's IComparable CompareTo");
                return CompareTo(obj);
            }

            public virtual int CompareTo(object obj)
            {
                Console.WriteLine("Base's virtual CompareTo");
                return 0;
            }
        }

        private class Derived : Base, IDisposable, IComparable
        {
            new internal void Dispose()
            {
                Console.WriteLine("Derived's Dispose");
                base.Dispose();
            }

            public override int CompareTo(object obj)
            {
                Console.WriteLine("Derived's CompareTo");
                return base.CompareTo(obj);
            }
        }

        internal static void C04()
        {
            string s = "Jeffrey";
            ICloneable cloneable = s;
            IComparable comparable = s;
            IEnumerable enumerable = (IEnumerable)comparable;
        }

        private sealed class SimpleType : IDisposable
        {
            internal void Dispose()
            {
                Console.WriteLine("internal Dispose");
            }

            void IDisposable.Dispose()
            {
                Console.WriteLine("IDisposeable Dispose");
            }
        }

        internal static void C05()
        {
            SimpleType st = new SimpleType();
            st.Dispose();
            IDisposable d = st;
            d.Dispose();
        }

        private sealed class Number : IComparable<int>, IComparable<string>
        {
            private int val = 5;

            public int CompareTo(int other)
            {
                return val.CompareTo(other);
            }

            public int CompareTo(string other)
            {
                return val.CompareTo(int.Parse(other));
            }
        }

        internal static void C06()
        {
            Number n = new Number();
            IComparable<int> cint = n;
            int result = cint.CompareTo(5);
            IComparable<string> cstr = n;
            result = cstr.CompareTo("5");
        }

        private sealed class SomeType1
        {
            private static void Test()
            {
                int x = 5;
                string g = "g";
                M(x);
                M(g);
            }

            private static int M<T>(T t)
                where T : IComparable, IConvertible
            {
                return 0;
            }
        }

        private interface IWindow
        {
            object GetMenu();
        }

        private interface IRestaurant
        {
            object GetMenu();
        }

        private sealed class MarioPizzeria : IWindow, IRestaurant
        {

            object IWindow.GetMenu()
            {
                return null;
            }

            object IRestaurant.GetMenu()
            {
                return null;
            }

            internal object GetMenu()
            {
                return null;
            }
        }

        internal static void C08()
        {
            MarioPizzeria mp = new MarioPizzeria();
            mp.GetMenu();
            IWindow window = mp;
            window.GetMenu();
            IRestaurant restaurant = mp;
            restaurant.GetMenu();
        }

        private struct SomeValueType : IComparable
        {
            private int x;

            internal SomeValueType(int x)
            {
                this.x = x;
            }

            internal int CompareTo(SomeValueType obj)
            {
                return x - obj.x;
            }

            int IComparable.CompareTo(object obj)
            {
                return CompareTo((SomeValueType)obj);
            }
        }

        internal static void C09()
        {
            SomeValueType v = new SomeValueType(0);
            object o = new object();
            int n = v.CompareTo(v);
            int x = 5;
            float f = ((IConvertible)x).ToSingle(null);
        }
    }
}
